---
title: PXF故障排查
---

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->


## <a id="pxf-errors"></a>PXF错误
下表描述了使用PXF时可能会遇到的一些错误：

| Error Message                 | Discussion                     |
|-------------------------------|---------------------------------|
| Protocol "pxf" does not exist | **Cause**: pxf扩展名未注册。<br>**Solution**: 按照PXF启用过程中的说明为[Enable Procedure](using_pxf.html#enable-pxf-ext) 为数据库创建（启用）PXF扩展 |
| Invalid URI pxf://\<path-to-data\>: missing options section | **Cause**: `LOCATION` URI配置项不包括配置或其他需要的信息。<br>**Solution**:在URI中提供配置和必需的选项。|
| org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: hdfs://\<namenode\>:8020/\<path-to-file\> | **Cause**: 在\<path-to-file\>中指定的HDFS文件不存在。<br>**Solution**: 指定现有HDFS文件的路径|
| NoSuchObjectException(message:\<schema\>.\<hivetable\> table not found) | **Cause**: \<schema\>.\<hivetable\>指定的Hive表不存在。<br>**Solution**: 提供存在的Hive表的名称。|
| Failed to connect to \<segment-host\> port 5888: Connection refused (libchurl.c:944)  (\<segment-id\> slice\<N\> \<segment-host\>:40000 pid=\<process-id\>)<br> ... |**Cause**: 在\<segment-host\>主机上PXF未运行。 <br>**Solution**: \<segment-host\>主机上重启PXF|
| *ERROR*: failed to acquire resources on one or more segments<br>*DETAIL*:  could not connect to server: Connection refused<br>&nbsp;&nbsp;&nbsp;&nbsp;Is the server running on host "\<segment-host\>" and accepting<br>&nbsp;&nbsp;&nbsp;&nbsp;TCP/IP connections on port 40000?(seg\<N\> \<segment-host\>:40000) | **Cause**: GPDB集群 \<segment-host\> 节点down |
| org.apache.hadoop.security.AccessControlException: Permission denied: user=<user>, access=READ, inode=&quot;<filepath>&quot;:<user>:<group>:-rw------- | **Cause**: 执行PXF操作的Greenplum数据库用户无权访问基础Hadoop服务（HDFS或Hive）。参阅[Configuring User Impersonation and Proxying](pxfuserimpers.html). |

## <a id="pxf-logging"></a>PXF日志

启用更详细的日志记录可能有助于PXF故障排除工作。 PXF提供了两类消息日志记录：服务级别和客户端级别。

### <a id="pxfsvclogmsg"></a>服务级别日志记录

PXF利用`log4j`进行服务级别的日志记录。PXF-service-related日志消息捕获由`$PXF_CONF/conf/pxf-log4j.properties`文件中的`log4j`控制。默认的PXF日志记录配置会将INFO和更严格的日志记录写入`$PXF_CONF/logs/pxf-service.log`。您可以配置日志记录级别和日志文件位置。

启用`DEBUG`级别时，PXF提供更详细的日志记录。要配置PXF`DEBUG`日志记录并检查输出，请执行以下操作：

1. 登录gpdb集群的master主机

    ``` shell
    $ ssh gpadmin@<gpmaster>
    ```

1. 使用编辑器打开 `$PXF_CONF/conf/pxf-log4j.properties`，取消以下行的注释，保存文件，然后退出编辑器：

    ``` shell
    #log4j.logger.org.greenplum.pxf=DEBUG
    ```

2. 使用 `pxf cluster sync` 命令拷贝更新的文件 `pxf-log4j.properties` 到每个segment主机。例如：

    ``` shell
    gpadmin@gpmaster$ $GPHOME/pxf/bin/pxf cluster sync
    ```

3. 依照[Restarting PXF](cfginitstart_pxf.html#restart_pxf)章节描述，重启gpdb集群的每个segment节点的pxf

4. 现在启用了`DEBUG`级别的日志记录，您可以执行PXF操作。 确保记下时间； 这会将信息定向输出到 `$PXF_CONF/logs/pxf-service.log`中的相关日志。

    ``` shell
    $ date
    Wed Oct  4 09:30:06 MDT 2017
    $ psql -d <dbname>
    ```

4. 创建和查询外部表。例如：

    ``` sql
    dbname=> CREATE EXTERNAL TABLE hdfstest(id int, newid int)
        LOCATION ('pxf://data/dir/hdfsfile?PROFILE=hdfs:text')
        FORMAT 'TEXT' (delimiter='E',');
    dbname=> SELECT * FROM hdfstest;
    <select output>
    ```

5. 最后，从`pxf-service.log`检查/收集日志消息。

**Note**: `DEBUG` 记录非常冗长，并且会对性能产生影响. 在收集了所需的信息之后，请关闭PXF服务的`DEBUG`日志记录。


### <a id="pxfdblogmsg"></a>客户端级别日志记录

数据库级客户端日志记录可以提供对内部PXF服务操作的了解。

在psql会话中将`client_min_messages`服务器配置参数设置为`DEBUG2`，可以在对PXF外部表进行操作期间启用Greenplum数据库及PXF调试消息日志记录。

``` shell
$ psql -d <dbname>
```

``` sql
dbname=# SET client_min_messages=DEBUG2;
dbname=# SELECT * FROM hdfstest;
...
DEBUG2:  churl http header: cell #19: X-GP-URL-HOST: seghost1  (seg0 slice1 127.0.0.1:40000 pid=3981)
CONTEXT:  External table hdfstest
DEBUG2:  churl http header: cell #20: X-GP-URL-PORT: 5888  (seg0 slice1 127.0.0.1:40000 pid=3981)
CONTEXT:  External table hdfstest
DEBUG2:  churl http header: cell #21: X-GP-DATA-DIR: data/dir/hdfsfile  (seg0 slice1 127.0.0.1:40000 pid=3981)
CONTEXT:  External table hdfstest
DEBUG2:  churl http header: cell #22: X-GP-OPTIONS-PROFILE: hdfs:text  (seg0 slice1 127.0.0.1:40000 pid=3981)
CONTEXT:  External table hdfstest
...
```

检查/收集来自stdout的日志消息

**Note**: `DEBUG2`数据库会话日志记录会影响性能。记住，在收集了所需的信息之后，请关闭`DEBUG2`日志记录。

``` sql
dbname=# SET client_min_messages=NOTICE;
```

## <a id="pxf-memcfg"></a>解决PXF内存问题

因为单个PXF客户端服务（JVM）为segment主机上的多个segment实例提供服务，所以PXF堆大小可能是限制运行的瓶颈。在并发工作负载时针对大文件的查询，影响更加明显。您可能会遇到由于内存不足或Java垃圾收集器影响响应时间而导致查询挂起或失败的情况。要避免或纠正这些情况，请首先尝试增加Java最大堆大小或减少Tomcat最大线程数，这取决于最适合您系统配置的方式。

**Note**: 本主题中描述的配置更改需要在Greenplum数据库集群中的每个segment节点上修改配置文件。执行更新后，请确保将PXF配置同步到群集中的每个segment主机。

在任何PXF版本升级之后，您将需要重新加载这些配置更改。

### <a id="pxf-heapcfg"></a>为PXF增加JVM内存

在segment主机上运行的每个PXF代理都配置有默认的最大Java堆大小2GB和初始堆大小1GB。 如果Greenplum数据库群集中的segment主机具有足够的内存，请尝试将最大堆大小增加到3-4GB之间的值。 如果可以，将初始堆大小和最大堆大小设置为相同的值最佳。

执行以下过程来增加在Greenplum数据库集群中每个segment主机上运行的PXF代理服务的堆大小。

1. 登录gpdb集群的master主机

    ``` shell
    $ ssh gpadmin@<gpmaster>
    ```

2. 重新进入PXF用户配置目录的位置（$ PXF_CONF）。编辑`$PXF_CONF/conf/pxf-env.sh`文件。 例如：

    ``` shell
    gpadmin@gpmaster$ vi $PXF_CONF/conf/pxf-env.sh
    ```

3. 在p`xf-env.sh`文件中找到`PXF_JVM_OPTS`设置，然后将 `-Xmx` 和/或 `-Xms` 选项更新为所需的值。 例如：

    ``` shell
    PXF_JVM_OPTS="-Xmx3g -Xms3g"
    ```

4. 使用`pxf cluster sync` 命令将更新的`pxf-env.sh`文件复制到每个Greenplum数据库segment主机。 例如：

    ``` shell
    gpadmin@gpmaster$ $GPHOME/pxf/bin/pxf cluster sync
    ```

5. 依照[Restarting PXF](cfginitstart_pxf.html#restart_pxf)描述，重启每个segment主机上的pxf服务。

### <a id="pxf-threadcfg"></a>资源受限的PXF segment主机的另一种选择

如果增加最大堆大小不适合您的Greenplum数据库部署，请尝试减少PXF的的并发工作线程数。正在运行的线程数量的减少将防止任何PXF节点耗尽其内存，同时确保当前查询运行完毕（尽管速度稍慢）。 Tomcat的默认行为是将请求排队，直到线程空闲或队列耗尽为止。

Tomcat的默认最大线程数为300。将最大线程数减少为最适合您的Greenplum数据库部署的值。（如果计划在外部Hive数据存储中的大量文件上运行大型工作负载，请指定一个更低的值。）

执行以下过程，以减少在Greenplum数据库部署中每个segment主机上运行的PXF代理的Tomcat线程的最大数量。

1. 登录到gpdb集群的master节点

    ``` shell
    $ ssh gpadmin@<gpmaster>
    ```

2. 编辑`$GPHOME/pxf/pxf-service/conf/server.xml`。例如:

    ``` shell
    gpadmin@gpmaster$ vi $GPHOME/pxf/pxf-service/conf/server.xml
    ```

3. 找到`Catalina` `Executor`区域，并将`maxThreads`设置更新为所需值。 例如：

    ``` xml
    <Executor maxThreads="100"
              minSpareThreads="50"
              name="tomcatThreadPool"
              namePrefix="tomcat-http--"/>
    ```

4. 将更新的`server.xml`文件复制到每个Greenplum数据库segment主机。 例如，如果`seghostfile`包含Greenplum数据库集群中seg主机的列表：

    ``` shell
    gpadmin@gpmaster$ gpscp -v -f seghostfile $GPHOME/pxf/pxf-service/conf/server.xml =:/usr/local/greenplum-db/pxf/pxf-service/conf/server.xml
    ```

5. 依照[Restarting PXF](cfginitstart_pxf.html#restart_pxf)描述重启PXF服务

## <a id="pxf-timezonecfg"></a>解决PXF JDBC连接器时区错误

您可以使用PXF JDBC连接器访问存储在外部SQL数据库中的数据。如果为PXF服务器设置的默认时区与为外部SQL数据库设置的时区不匹配，则取决于JDBC驱动程序，该程序可能会返回错误。

例如，如果使用PXF JDBC连接器访问时区冲突的Oracle数据库，则PXF会记录类似于以下内容的错误：

``` pre
SEVERE: Servlet.service() for servlet [PXF REST Service] in context with path [/pxf] threw exception
java.io.IOException: ORA-00604: error occurred at recursive SQL level 1
ORA-01882: timezone region not found
```

如果遇到此错误，可以在`$PXF_CONF/conf/pxf-env.sh`配置文件中的`PXF_JVM_OPTS`属性设置中为PXF服务器设置默认时区选项。 例如，要设置时区：

``` pre
export PXF_JVM_OPTS="<current_settings> -Duser.timezone=America/Chicago"
```

您也可以使用`PXF_JVM_OPTS`属性来设置其他Java选项。

如前几节所述，您必须将更新的PXF配置同步到每个Greenplum数据库segment主机，然后在每个主机上重新启动PXF服务。

